local math = math
local pairs = pairs
local ipairs = ipairs
local type = type
local table = table
local tabletool = require "tabletool"
local timetool = require "timetool"
local base = require "base"
local filelog = require "filelog"
require "enum"

require "nncardvalue"
--[[
    牛牛牌型判断
]]
local cardTool = {}

local function calculate_cardtype(card)
    return (card // 16)
end

local function calculate_cardvalue(card)
    return (card % 16)
end

--从大到小排序
local function comps(card1, card2)
    local value1 = calculate_cardvalue(card1)
    local value2 = calculate_cardvalue(card2)
    if value1 > value2 then
        return true
    elseif value1 == value2 and calculate_cardtype(card1) > calculate_cardtype(card2)  then
        return true
    end 
    return false
end

--计算累计牌值
local function calculate_niu_totalvalue(cards)
    local total_card_value = 0
    local card_value
    for _, card in ipairs(cards) do
        card_value = calculate_cardvalue(card)
        if card_value >= 10 then
            total_card_value = total_card_value + 10
        else
            total_card_value = total_card_value + card_value
        end 
    end

    return total_card_value
end

local function cards_shuffle(cards)
    -- 洗牌
    local index
    local tmp_seed
    tmp_seed = base.RNG()
    if tmp_seed == nil then
        tmp_seed = timetool.get_10ms_time()
    end

    for i = 1, #CardData do
        math.randomseed(tmp_seed + 11*i)    
        index = math.random(#CardData + 1 - i)
        CardData[index], CardData[#CardData + 1 - i] = CardData[#CardData + 1 - i], CardData[index]
    end
end

--@des 获得新的牌堆
function cardTool.get_new_cards(cards)

    if cards ~= nil then
       return tabletool.deepcopy(cards) 
    end

    cards_shuffle()

    return tabletool.deepcopy(CardData)
end

--@des 获得固定牌型的牌堆
function cardTool.get_fixed_cards(cards)
    math.randomseed(timetool.get_time())

    local index = math.random(#FixedCardData)
    return tabletool.deepcopy(FixedCardData[index]) 
end

--@des 对传入的牌按牌值由大到小排序
function cardTool.from_ztoa_sort(cards)
    table.sort(cards, comps)
end

--@des 判断是否同花
function cardTool.is_withflowers(cards)
    local card_type = calculate_cardtype(cards[1])
    for i=2, #cards do
        if card_type ~= calculate_cardtype(cards[i]) then
            return false
        end 
    end
    return true    
end

--@des 判断是否顺子
function cardTool.is_flush(cards)
    local card_value = calculate_cardvalue(cards[1])

    --判断特殊顺子牌型
    if card_value == 13 and calculate_cardvalue(cards[#cards]) == 1 then
        for i=2, #cards - 1 do
            if card_value ~= (calculate_cardvalue(cards[i]) + 1) then
                return false
            else
                card_value = calculate_cardvalue(cards[i])
            end
        end
    else
        for i=2, #cards do
            if card_value ~= (calculate_cardvalue(cards[i]) + 1) then
                return false
            else
                card_value = calculate_cardvalue(cards[i])
            end
        end        
    end
    return true
end

--@des 判断是否同花顺
function cardTool.is_straightflush(cards)
    return (cardTool.is_withflowers(cards) and cardTool.is_flush(cards))
end

--@des 判断是否炸弹
function cardTool.is_bomb(cards)
    local num = 0
    local card_value = 0
    for i=1, 2 do
        num = 1
        card_value = calculate_cardvalue(cards[i])
        for j=i+1, #cards do
            if card_value == calculate_cardvalue(cards[j]) then
                num = num + 1
            end
        end
        if num >= 4 then
            return true
        end
    end
    return false
end

--@des 判断是否葫芦
function cardTool.is_bottlegourd(cards)
    local num = 0
    local card_value = 0
    for i=1, 3 do
        num = 1
        card_value = calculate_cardvalue(cards[i])
        for j=i+1, #cards do
            if card_value == calculate_cardvalue(cards[j]) then
                num = num + 1
            end
        end
        if num >= 3 then
            local duizi_card_value = 0
            for k=1, #cards do
                if calculate_cardvalue(cards[k]) ~= card_value then
                    if duizi_card_value == 0 then
                        duizi_card_value = calculate_cardvalue(cards[k])
                    elseif duizi_card_value == calculate_cardvalue(cards[k]) then
                        return true
                    end
                end
            end
        end        
    end

    return false
end

--@des 判断是否五小牛
function cardTool.is_fivecalves(cards)
    if calculate_cardvalue(cards[1]) >= 5 then
        return false
    end 

    local total_card_value = 0
    for _, card in ipairs(cards) do
        total_card_value = total_card_value + calculate_cardvalue(card)
    end
    if total_card_value <= 10 then
        return true
    end 
    return false 
end

--@des 判断是否五花牛
function cardTool.is_wuhuacattle(cards)
    if calculate_cardvalue(cards[5]) > 10 then
        return true
    end
    return false
end

function cardTool.calculate_cardvalue(card)
    return calculate_cardvalue(card)
end

function cardTool.get_niu_cards(cards)
    local total_card_value = 0
    local card_value = 0
    for i=1, #cards do        
        for j=i+1, #cards do
            total_card_value = calculate_cardvalue(cards[i])
            if total_card_value > 10 then
                total_card_value = 10
            end
            card_value = calculate_cardvalue(cards[j])
            if card_value > 10 then
                card_value = 10                
            end            
            total_card_value = total_card_value + card_value

            for k=j+1, #cards do
                card_value = calculate_cardvalue(cards[k])
                if card_value > 10 then
                    card_value = 10                
                end
                if ((total_card_value+card_value) % 10) == 0 then
                    return {cards[i], cards[j], cards[k]}
                end
            end
        end
    end
    return nil
end

--比较两个玩家牌型大小, 表示seat1是否大于seat2
function cardTool.compare_card_type(seat1, seat2)
    if seat1.card_type > seat2.card_type then
        return true
    end

    if seat1.card_type < seat2.card_type then
        return false
    end

    local cards1 = tabletool.deepcopy(seat1.final_cards)
    local cards2 = tabletool.deepcopy(seat2.final_cards)
    cardTool.from_ztoa_sort(cards1)
    cardTool.from_ztoa_sort(cards2)

    local value1, value2
    value1 = calculate_cardvalue(cards1[1])
    value2 = calculate_cardvalue(cards2[1])
    if  value1 > value2 then
        return true
    elseif value1 < value2 then
        return false
    else
        if calculate_cardtype(cards1[1]) > calculate_cardtype(cards2[1]) then
            return true
        else
            return false
        end
    end

    return false
end


--分析玩家牌型
function cardTool.analysis_card_type(seat, cards)
    cardTool.from_ztoa_sort(cards)

    local is_flush = false

    if cardTool.is_withflowers(cards) then
        if cardTool.is_flush(cards) then
            seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_TONGHUASHUN
            is_flush = true
            return                    
        end
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_TONGHUA
        return
    end

    if cardTool.is_bomb(cards) then
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_ZHADAN
        return
    end

    if cardTool.is_bottlegourd(cards) then
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_HULU
        return
    end

    if cardTool.is_flush(cards) then
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_SHUNZI
        return
    end

    if cardTool.is_fivecalves(cards) then
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_WUXIAONIU
        return        
    end

    if cardTool.is_wuhuacattle(cards) then
        seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_WUHUANIU
        return
    end

    local niu_cards = cardTool.get_niu_cards(cards)
    if niu_cards ~= nil then
        local is_find = false
        seat.cards = niu_cards
        for _, card in ipairs(cards) do
            is_find = false
            for _, tmpcard in ipairs(seat.cards) do
                if card == tmpcard then
                    is_find = true
                    break
                end
            end
            if not is_find then
                table.insert(seat.cards, card)
            end
        end
        seat.card_type = calculate_niu_totalvalue(seat.cards) % 10
        if seat.card_type == 0 then
            seat.card_type = 10
        end
        return
    end
    
    seat.card_type = ENNBaseCardType.NNBASE_CARD_TYPE_UNKNOW    
end

return cardTool
